package legato.actions
{
	
	import legato.tasks.TaskManager;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;
	import mx.events.PropertyChangeEvent;
	
	import mx.core.ClassFactory;
	import mx.resources.ResourceManager;

	[ResourceBundle("ActionsFramework")]
	[Event(name="propertyChange", type="mx.events.PropertyChangeEvent")]
	[Event(name="complete", type="flash.events.Event")]
	
	/**
	 * Basic abstract action for all built in and custom actions. Loads label, icon and tooltipText from ActionsFramework.properties file.
	 * Use action name as an identifier. Example of ActionsFramework.properties file : 
	 * [code]
	 * 	addChildTaskAction.label=New child task...
		addChildTaskAction.tooltipText=Create child new task
		addChildTaskAction.icon=Embed('../../embeded/add_child.png')


		deleteTaskAction.label=Delete task
		deleteTaskAction.tooltipText=Delete selected task
		deleteTaskAction.icon=Embed('../../embeded/delete.png')
 		[/code]
	 * @author Piotr
	 * 
	 */
	public class AbstractAction extends EventDispatcher implements IAction
	{
		protected var initialEvent:Event;
		
		private var _icon:*;
		
		private var _name:String;
		
		private var _label:String;
		
		private var _tooltipText:String;
		
		private var _saveCopy:Boolean;
		
		private const BUNDLE_NAME:String = "ActionsFramework";
		
		[Bindable]
		/**
		 *  
		 * Icon used by visual components
		 * 
		 */
		public function get icon():*
		{
			return _icon;
		}
	
		public function set icon(val:*):void
		{
			_icon=val;
		}
	
		[Bindable]
		/**
		 *  
		 * The name of action. Used to identify resources in ActionsFramework.properties file
		 * 
		 */
		public function get name():String
		{
			return _name;
		}
	
		public function set name(val:String):void
		{
			_name=val;
			this.loadResources();
		}
	
		[Bindable]
		/**
		 * Tooltip used by visual components
		 * 
		 */
		public function get tooltipText():String
		{
			return _tooltipText;
		}
	
		public function set tooltipText(val:String):void
		{
			_tooltipText=val;
		}

		[Bindable]
		/**
		 * Label used by visual componens, for example button label
		 * 
		 */
		public function get label():String
		{
			return _label;
		}
	
		public function set label(val:String):void
		{
			_label=val;
		}
		/**
		 * If set to true action is duplicated before execution and the copy is stored in TaskManager 
		 * 
		 */
		public function get saveCopy():Boolean
		{
			return this._saveCopy;
		}
		
		public function set saveCopy(val:Boolean):void
		{
			this._saveCopy = val;
		}
				
		/**
		 * Constructor 
		 */
		public function AbstractAction()
		{
			this.saveCopy = false;
			ResourceManager.getInstance().addEventListener("change",langChange);
		}
		
		/**
		 * Loads label, tooltip and icon from resource bundle. 
		 */
		public function loadResources():void {
			this.label = ResourceManager.getInstance().getString(BUNDLE_NAME,this.name+".label");
			this.tooltipText = ResourceManager.getInstance().getString(BUNDLE_NAME,this.name+".tooltipText");
			this.icon = ResourceManager.getInstance().getClass(BUNDLE_NAME,this.name+".icon");
			this.dispatchEvent(new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE));

		}
		
		/**
		 * Starts execution of an action. This method is used by visual components to run an action.
		 * @param event the event object prpagated from visual component, for example mose click event
		 * 
		 */
		public final function invoke(event:Event):void
		{
			this.initialEvent = event;
			TaskManager.instance.executeAction(this);
		}
		
		/**
		 * Executes an action. This method is meant to be overwriten
		 * in custom actions.
		 */
		public function execute():void
		{
			
		}
		
		/**
		 * Creates copy of action before execution. This method is meant to be overwriten
		 * in custom actions.
		 * @return 
		 * 
		 */
		public function createCopy():IAction
		{
			var factory:ClassFactory = new ClassFactory(getDefinitionByName(getQualifiedClassName(this)) as Class);
			var actionCopy:AbstractAction = AbstractAction(factory.newInstance());
			actionCopy.icon = this.icon;
			actionCopy.name = this.name;
			actionCopy.label = this.label;
			actionCopy.tooltipText = this.tooltipText;
			actionCopy.saveCopy = this.saveCopy;
			actionCopy.initialEvent = this.initialEvent;
			return actionCopy;
		}
		
		private function langChange(evt:Event):void
		{
			this.loadResources();
		}
	}
}